我们就已经详细分析过前端模块化的发展历史,谈到 ESM 已经逐步得到各大浏览器厂商以及 Node.js 的原生支持,正在成为主流前端模块化方案。而 Vite 本身就是借助浏览器原生的 ESM 解析能力(type="module")实现了开发阶段的 no-bundle,即不用打包也可以构建 Web 应用。不过我们对于原生 ESM 的理解仅仅停留在 type="module"这个特性上面未免有些狭隘了,一方面浏览器和 Node.js 各自提供了不同的 ESM 使用特性,如 import maps、package.json 的 imports和exports 属性等等,另一方面前端社区开始逐渐向 ESM 过渡,有的包甚至仅留下 ESM 产物,Pure ESM 的概念随之席卷前端圈,而与此同时,基于 ESM 的 CDN 基础设施也如雨后春笋般不断涌现,诸如esm.sh、skypack、jspm等等。
因此你可以看到,ESM 已经不仅仅局限于一个模块规范的概念,它代表了前端社区生态的走向以及各项前端基础设施的未来,不管是浏览器、Node.js 还是 npm 上第三方包生态的发展,无一不在印证这一点。那么,作为一名 2022 年的前端,我觉得深入地了解 ESM 的高级特性、社区生态都是有必要的,一方面弥补自己对于 ESM 认知上的不足,另一方面也能享受到社区生态带给我们的红利。
在接下来的内容中,我将给你详细介绍浏览器和 Node.js 中基于 ESM 实现的一些高级特性,然后分析什么是 Pure ESM 模式,这种模式下存在哪些痛点,以及我们作为开发者,如何去拥抱Pure ESM的趋势。
# 高阶特性
# import map
在浏览器中我们可以使用包含type="module"属性的script标签来加载 ES 模块,而模块路径主要包含三种:
- 绝对路径,如
https://cdn.skypack.dev/react - 相对路径,如
./module-a bare import即直接写一个第三方包名,如react、lodash
对于前两种模块路径浏览器是原生支持的,而对于 bare import,在 Node.js 能直接执行,因为 Node.js 的路径解析算法会从项目的 node_modules 找到第三方包的模块路径,但是放在浏览器中无法直接执行。而这种写法在日常开发的过程又极为常见,除了将 bare import 手动替换为一个绝对路径,还有其它的解决方案吗?
答案是有的。现代浏览器内置的 import map 就是为了解决上述的问题,我们可以用一个简单的例子来使用这个特性:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script type="importmap">
{
"imports": {
"react": "https://cdn.skypack.dev/react"
}
}
</script>
<script type="module">
import React from 'react';
console.log(React)
</script>
</body>
</html>
